package com.amado.course53EncodeDecode;

import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/*-----BEGIN PRIVATE KEY pkcs#8-----
        MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEA5NhwCWfVL76Rm0xD
        ESXhLJ4gNaT2c2boxlImIbpBTBh6Di0jJx+fjkc4xNGwTgoTg5sOGHw5GeER4rnM
        3IhikwIDAQABAkBdFtoESXOEF24dkRkbCaCeSLhree4ypWL9AX+3ao+TRwCBe4oa
        4ng2u72kV9IXXd3Uh0lOax+9bbkwMDybq/LZAiEA/gny9DQ7TZs7bPujNloa16GT
        RueVQcKj/EZ5v22BEQ8CIQDmnLMRIM6HzzCXGD8Jdt5ZshoVIT7eSp2685fEG5+O
        PQIgEj3gpkyB3abB86d2Jtb9inJdwv+qJhi18c2VvHs+g10CIQDQ4isIXrD0LuWS
        VrHyfqsUj9A0R3LMosWQK0jSpzq0+QIgaoM41TUQsI2VbGV5ty0pL4GWKh+y00Sr
        ndtjLJ3WZTY=
        -----END PRIVATE KEY-----*/

/*-----BEGIN PUBLIC KEY-----
        MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOTYcAln1S++kZtMQxEl4SyeIDWk9nNm
        6MZSJiG6QUwYeg4tIycfn45HOMTRsE4KE4ObDhh8ORnhEeK5zNyIYpMCAwEAAQ==
        -----END PUBLIC KEY-----*/



public class RSAService {

    public static void main(String[] args) throws Exception {
        KeyPair keyPair = getKeyPair();
//        String privateKey = new String(Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()));
//        String publicKey = new String(Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()));

        String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJqMs53AUwgFDyTdbjz97hsiPYQVzc79PniiIs6T4pCACSe+ZQcmn/Vqs3yD22MBoEo9JvOdN7hlhfdVcjtVNEXsOGLX68KRqzU7BaR3DNlaDcs6p9Q5EXe0Wa806IsvMlDofmguw01mMw6vZBmubiyvNzVpfc7QFHBCE+Q/9eFjAgMBAAECgYBu5tBtPvlWI+s+FPdqJP2b0vI5uju5cNhHUHGRs2U9M+Nd9a4hd4IJZcvuaeAgJ6aSH1e4MPUvCQsc9N/H29hpxD+7wWVwnTpIIVy4rgSzkDheGZodQjqtoJTQXzqewEhb+drqtCvJTVEr28k/2q8gMXkNk9Rctlwf/D2NjE5qoQJBAOVQPNtJT0fY1fROsVURFmcM/77viz8LiN7+wl3yvFXwXt92DqSAAk034KH0pai7KGVM+Fgqvt2TjUrzUotNur8CQQCsiRT5mfgeXckOundPM3kmt6R5kCO4EbxBfqE3qki5pW4+0jGyukgbxs5vvXjr/Ut8wEji5CQpJv1aj9kBm3ZdAkBSE2sEzfN7csf5nqToHqqXDdcH3zNGyHkf361v9O6mD9fVQasyA8NPIh3bufYFM5/cyjTlUb9pDWP4HKlBxPt/AkBiuASSVDCNX2f8z2AYpwD40DaBf6GQXkVyy/t+mCYIYslTlHzvIHrFudjAQo7/p+wbMwIBIDw4d6CawpeNvd/ZAkEA29WTAl94zp0X3U6JWyqtn8Ci9jibhhbB0/vpA5igKK1zXg6ir7vk6Tp/hsi48tgYrFd6rciWt4jwpeFv7HDhTA==";
        String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCajLOdwFMIBQ8k3W48/e4bIj2EFc3O/T54oiLOk+KQgAknvmUHJp/1arN8g9tjAaBKPSbznTe4ZYX3VXI7VTRF7Dhi1+vCkas1OwWkdwzZWg3LOqfUORF3tFmvNOiLLzJQ6H5oLsNNZjMOr2QZrm4srzc1aX3O0BRwQhPkP/XhYwIDAQAB";

        System.out.println("私钥："+privateKey);
        System.out.println();
        System.out.println("公钥："+publicKey);

        String value = "{\"name22222222222222222222222222222name22222222222222222222222222222222222222222222222222444444444444444444444442222name22222222222222222222222222222222222222222222222222444444444444444444444442222name22222222222222222222222222222222222222222222222222444444444444444444444442222222222222222222222222444444444444444444444442222\":\"dd\"}";
        String sign = sign(value,privateKey);
        System.out.println("签名："+sign);
        System.out.println(verify(value,publicKey,sign));
    }

    public static KeyPair getKeyPair() throws Exception {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(1024);
        return generator.generateKeyPair();
    }

    /**
     * 签名
     *
     * @param data 待签名数据
     * @return 签名
     */
    public static String sign(String data, PrivateKey privateKey) throws Exception {
        byte[] keyBytes = privateKey.getEncoded();
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey key = keyFactory.generatePrivate(keySpec);
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initSign(key);
        signature.update(data.getBytes());
//        return Base64.getEncoder().encodeToString(signature.sign());
        return new String(Base64.getEncoder().encodeToString(signature.sign()));
    }

    /**
     * 签名
     *
     * @param data 待签名数据
     * @return 签名
     */
    public static String sign(String data, String key) throws Exception {
        PKCS8EncodedKeySpec encodeKey = new PKCS8EncodedKeySpec(
                Base64.getDecoder().decode(key.getBytes()));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(encodeKey);
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initSign(privateKey);
        signature.update(data.getBytes());
//        return Base64.getEncoder().encodeToString(signature.sign());
        return new String(Base64.getEncoder().encodeToString(signature.sign()));
    }

    /**
     * 验签
     *
     * @param srcData 原始字符串
     * @param sign    签名
     * @return 是否验签通过
     */
    public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception {
        byte[] keyBytes = publicKey.getEncoded();
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey key = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initVerify(key);
        signature.update(srcData.getBytes());
//        return signature.verify(java.util.Base64.getDecoder().decode(sign.getBytes()));
        return signature.verify(Base64.getDecoder().decode(sign.getBytes()));
    }
    /**
     * 验签
     *
     * @param srcData 原始字符串
     * @param sign    签名
     * @return 是否验签通过
     */
    public static boolean verify(String srcData, String key, String sign) throws Exception {
        X509EncodedKeySpec encodeKey = new X509EncodedKeySpec(
                Base64.getDecoder().decode(key.getBytes()));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(encodeKey);
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initVerify(publicKey);
        signature.update(srcData.getBytes());
//        return signature.verify(java.util.Base64.getDecoder().decode(sign.getBytes()));
        return signature.verify(Base64.getDecoder().decode(sign.getBytes()));
    }
}
